﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ProjetoJornada_DAL;
using Basicas;
using MySql.Data.MySqlClient;
using Basicas.Utils;
using System.Data;

namespace ProjetoJornada_DAL.Repositorio
{
    public class RepTurma
    {
        private DAO dao;

        #region Construtor
        public RepTurma()
        {
            this.dao = DAO.Instance;
        } 
        #endregion

        #region Metodos Públicos
        public Int32 Inserir(Turma turma)
        {
            String storeProcedure = "sp_Turma_Inserir";

            try
            {
                MySqlParameter[] parametros = new MySqlParameter[9];

                parametros[0] = new MySqlParameter();
                parametros[0].ParameterName = @"LocalIn";
                parametros[0].Value = turma.Local;
                parametros[0].DbType = DbType.String;

                parametros[1] = new MySqlParameter();
                parametros[1].ParameterName = @"QtdeVagasIn";
                parametros[1].Value = turma.QtdeVagas;
                parametros[1].DbType = DbType.Int32;

                parametros[2] = new MySqlParameter();
                parametros[2].ParameterName = @"DataInicialIn";
                parametros[2].Value = turma.DataInicial;
                parametros[2].DbType = DbType.Date;

                parametros[3] = new MySqlParameter();
                parametros[3].ParameterName = @"HorariosIn";
                parametros[3].Value = turma.Horarios;
                parametros[3].DbType = DbType.String;

                parametros[4] = new MySqlParameter();
                parametros[4].ParameterName = @"DataFinalIn";
                parametros[4].Value = turma.DataFinal;
                parametros[4].DbType = DbType.Date;

                parametros[5] = new MySqlParameter();
                parametros[5].ParameterName = @"PrecoAtualIn";
                parametros[5].Value = turma.PrecoAtual;
                parametros[5].DbType = DbType.Double;

                parametros[6] = new MySqlParameter();
                parametros[6].ParameterName = @"Id_CursoJornadaIn";
                parametros[6].Value = turma.IdJornadaCurso;
                parametros[6].DbType = DbType.Int32;

                parametros[7] = new MySqlParameter();
                parametros[7].ParameterName = @"NomeIn";
                parametros[7].Value = turma.Nome;
                parametros[7].DbType = DbType.String;

                parametros[8] = new MySqlParameter();
                parametros[8].ParameterName = @"Result";
                parametros[8].DbType = DbType.Int32;
                parametros[8].Direction = ParameterDirection.Output;

                Int32 idTurma = (Int32)dao.ExecutaFuncao(parametros, storeProcedure);
                return idTurma;
            }
            catch (Exception ex)
            {
                Auxiliar.GravaLog(ex.Message, "InserirTurma - Repositorio");
                throw ex;
            }

        }
        public bool Editar(Turma turma)
        {

            this.RemoverTodosInstrutoresMonitorDaTurma(turma.Id);

            foreach (Instrutor_Monitor instrutor in turma.Instrutores)
            {
                InserirInstrutorNaTurma(instrutor.Cpf, turma.Id);
            }

            foreach (Instrutor_Monitor monitor in turma.Monitores)
            {
                InserirInstrutorNaTurma(monitor.Cpf, turma.Id);
            }


            String storeProcedure = "sp_Turma_Edit";

            try
            {
                MySqlParameter[] parametros = new MySqlParameter[10];

                parametros[0] = new MySqlParameter();
                parametros[0].ParameterName = @"IdIn";
                parametros[0].Value = turma.Id;
                parametros[0].DbType = DbType.Int32;

                parametros[1] = new MySqlParameter();
                parametros[1].ParameterName = @"LocalIn";
                parametros[1].Value = turma.Local;
                parametros[1].DbType = DbType.String;

                parametros[2] = new MySqlParameter();
                parametros[2].ParameterName = @"QtdeVagasIn";
                parametros[2].Value = turma.QtdeVagas;
                parametros[2].DbType = DbType.Int32;

                parametros[3] = new MySqlParameter();
                parametros[3].ParameterName = @"DataInicialIn";
                parametros[3].Value = turma.DataInicial;
                parametros[3].DbType = DbType.Date;

                parametros[4] = new MySqlParameter();
                parametros[4].ParameterName = @"HorariosIn";
                parametros[4].Value = turma.Horarios;
                parametros[4].DbType = DbType.String;

                parametros[5] = new MySqlParameter();
                parametros[5].ParameterName = @"DataFinalIn";
                parametros[5].Value = turma.DataFinal;
                parametros[5].DbType = DbType.Date;

                parametros[6] = new MySqlParameter();
                parametros[6].ParameterName = @"PrecoAtualIn";
                parametros[6].Value = turma.PrecoAtual;
                parametros[6].DbType = DbType.Double;

                parametros[7] = new MySqlParameter();
                parametros[7].ParameterName = @"Id_CursoJornadaIn";
                parametros[7].Value = turma.IdJornadaCurso;
                parametros[7].DbType = DbType.Int32;

                parametros[8] = new MySqlParameter();
                parametros[8].ParameterName = @"NomeIn";
                parametros[8].Value = turma.Nome;
                parametros[8].DbType = DbType.String;

                parametros[9] = new MySqlParameter();
                parametros[9].ParameterName = @"IdCursoIn";
                parametros[9].Value = turma.Curso.Id;
                parametros[9].DbType = DbType.Int32;

                return dao.ExecutaSql(parametros, storeProcedure);
            }
            catch (Exception ex)
            {
                Auxiliar.GravaLog(ex.Message, "EditarTurma - Repositorio");
                throw ex;
            }
        
        }
        public bool Remover(Turma turma)
        {
            String storeProcedure = "sp_Turma_Delete";

            try
            {
                MySqlParameter[] parametros = new MySqlParameter[1];

                parametros[0] = new MySqlParameter();
                parametros[0].ParameterName = @"IdIn";
                parametros[0].Value = turma.Id;
                parametros[0].DbType = DbType.Int32;

                return dao.ExecutaSql(parametros, storeProcedure);
            }
            catch (Exception ex)
            { 
                Auxiliar.GravaLog(ex.Message, "RemoverTurma - Repositorio");
                throw ex;
            }
        }
        
        public Turma Consultar(int idTurma)
        {

            String storeProcedure = "sp_Turma_Select_Id";
            Turma turma = null;
            MySqlDataReader dr = null;

            try
            {
                MySqlParameter[] parametros = new MySqlParameter[1];

                parametros[0] = new MySqlParameter();
                parametros[0].ParameterName = @"idTurmaIn";
                parametros[0].Value = idTurma;
                parametros[0].DbType = System.Data.DbType.Int32;

                dr = dao.ExecutaLeituraProcedure(parametros, storeProcedure);

                if (dr.Read())
                {                
                    turma = CarregarTurma(dr);
                }
                List<Instrutor_Monitor> instrutores  = new List<Instrutor_Monitor>();
                List<Instrutor_Monitor> monitores = new List<Instrutor_Monitor>();
                if (dr.NextResult())
                {
                    while (dr.Read())
                    {
                        string cpfInstrutor = dr["CPF_Instrutor"] as string;
                        Boolean ehInstrutor = dr.GetBoolean("eh_Instrutor");
                        Instrutor_Monitor instrutorMonitor = new Instrutor_Monitor()
                        {
                            Cpf = cpfInstrutor
                        };

                        if (ehInstrutor)
                        {
                            instrutores.Add(instrutorMonitor);
                        }
                        else
                        {
                            monitores.Add(instrutorMonitor);
                        }
                    }                
                }

                Curso curso = null;
                if (dr.NextResult())
                {
                    if (dr.Read())
                    {
                        string nomeCurso = dr["Nome"] as string;
                        int id = dr.GetInt32("Id");
                        curso = new Curso()
                        {
                            Id = id,
                            Nome = nomeCurso
                        };
                    }
                }
                turma.Instrutores = instrutores;
                turma.Monitores = monitores;
                turma.Curso = curso;

                return turma;
            }
            catch (Exception ex)
            {
                Auxiliar.GravaLog(ex.Message, "ConsultarTurmaPorId - Repositorio");
                throw ex;            
            }
            finally
            {
                if (dr != null)
                {
                    dr.Close();
                }

                dao.FecharConexao();
            }
        }
        public List<Turma> ConsultarTodasAsTurmasPorJornada(int IdJornada)
        {
            String storeProcedure = "sp_Turma_Select_Jornada";
            List<Turma> listaDeTurmas = new List<Turma>();
            MySqlDataReader dr = null;

            try
            {
                MySqlParameter[] parametros = new MySqlParameter[1];

                parametros[0] = new MySqlParameter();
                parametros[0].ParameterName = @"idJornadaIn";
                parametros[0].Value = IdJornada;
                parametros[0].DbType = DbType.Int32;

                dr = dao.ExecutaLeituraProcedure(parametros, storeProcedure);

                while (dr.Read())
                {
                    listaDeTurmas.Add(CarregarTurma(dr));
                }                
            }
            catch (Exception ex)
            {
                Auxiliar.GravaLog(ex.Message, "ConsultarTodasAsTurmasPorJornada - Turma");
                throw ex;
            }
            finally
            {
                if (dr != null)
                {
                    dr.Close();
                }

                dao.FecharConexao();
            }
            return listaDeTurmas;
        }

        public int GetQuantidadeDeTurmasNoCurso(int idCursoJornada)
        {
            string storedProcedure = "sp_GetQuantityTurmaNoCurso";

            try
            {
                MySqlParameter[] parametros = new MySqlParameter[2];

                parametros[0] = new MySqlParameter();
                parametros[0].ParameterName = @"idCursoJornadaIn";
                parametros[0].Value = idCursoJornada;
                parametros[0].DbType = System.Data.DbType.Int32;

                parametros[1] = new MySqlParameter();
                parametros[1].ParameterName = @"Result";
                parametros[1].DbType = System.Data.DbType.Int32;
                parametros[1].Direction = ParameterDirection.Output;

                int retorno = (int)dao.ExecutaFuncao(parametros, storedProcedure);

                return retorno;
            }
            catch (Exception ex)
            {
                Auxiliar.GravaLog(ex.Message, "GetQuantidadeDeTurmasNoCurso - Repositorio");
                throw ex;
            }
        }
        public bool InserirInstrutorNaTurma(string idInstrutor, int idTurma)
        {
            String storeProcedure = "sp_InstrutorTurma_Inserir";

            try
            {
                MySqlParameter[] parametros = new MySqlParameter[2];

                parametros[0] = new MySqlParameter();
                parametros[0].ParameterName = @"Id_TurmaIn";
                parametros[0].Value = idTurma;
                parametros[0].DbType = DbType.Int32;

                parametros[1] = new MySqlParameter();
                parametros[1].ParameterName = @"CPFInstrutorMonitor";
                parametros[1].Value = idInstrutor;
                parametros[1].DbType = DbType.String;

                return dao.ExecutaSql(parametros, storeProcedure);

            }
            catch (Exception ex)
            {
                Auxiliar.GravaLog(ex.Message, "InserirInstrutorNaTurma - RepositorioTurma");
                throw ex;
            }
        }
        public Int32 GetQuantidadeDeAlunos(Turma turma)
        {
            String storedProcedure = "sp_Turma_GetQuantityById";
            Int32 retorno = 0;

            try
            {
                MySqlParameter[] parametros = new MySqlParameter[2];
                
                parametros[0] = new MySqlParameter();
                parametros[0].ParameterName = @"IdIn";
                parametros[0].Value = turma.Id;
                parametros[0].DbType = DbType.Int32;

                parametros[1] = new MySqlParameter();
                parametros[1].ParameterName = @"Result";
                parametros[1].DbType = DbType.Int32;
                parametros[1].Direction = ParameterDirection.Output;

                retorno = (Int32) dao.ExecutaFuncao(parametros, storedProcedure);

                return retorno;
            }
            catch (Exception ex)
            {
                Auxiliar.GravaLog(ex.Message, "GetQuantidadeDeAlunos - RepositorioTurma");
                throw ex;
            }
        }
        private void RemoverTodosInstrutoresMonitorDaTurma(int idTurma)
        {
            String storeProcedure = "sp_InstrutorTurma_Delete_AllByTurma";

            try
            {
                MySqlParameter[] parametros = new MySqlParameter[1];

                parametros[0] = new MySqlParameter();
                parametros[0].ParameterName = @"idTurmaIn";
                parametros[0].Value = idTurma;
                parametros[0].DbType = DbType.Int32;

                dao.ExecutaSql(parametros, storeProcedure);
            }
            catch (Exception ex)
            {
                Auxiliar.GravaLog(ex.Message, "RemoverTurma - Repositorio");
                throw ex;
            }
        
        }

        /// <summary>
        /// Retorna a quantidade de alunos de todas as turmas de uma jornada
        /// </summary>
        /// <param name="idJornada">id da jornada a ser consultada</param>
        /// <returns>Dicionario, onde passado o id da turma, pode ser adquirido a quantidade de alunos da mesma</returns>
        public Dictionary<int,int> GetQuantidadeDeAlunosEmTodasAsTurmas(int idJornada)
        {
            string storeProcedure = "sp_GetQtdeAlunosNasTurmasJornada";
            Dictionary<int, int> retorno = new Dictionary<int,int>();
            MySqlDataReader dr = null;

            try
            {
                MySqlParameter[] parametros = new MySqlParameter[1];

                parametros[0] = new MySqlParameter();
                parametros[0].ParameterName = @"IdJornadaIn";
                parametros[0].Value = idJornada;
                parametros[0].DbType = DbType.Int32;

                dr = dao.ExecutaLeituraProcedure(parametros, storeProcedure);

                while (dr.Read())
                {
                    int idTurma = dr.GetInt32("Id_Turma");
                    int qtdeDeAlunos = dr.GetInt32("Qtde");

                    retorno.Add(idTurma, qtdeDeAlunos);
                }

                return retorno;
            }
            catch (Exception ex)
            {
                Auxiliar.GravaLog(ex.Message, "GetQuantidadeDeAlunosEmTodasAsTurmas - repTurma");
                throw ex;
            }
            finally
            {
                if (dr != null)
                {
                    dr.Close();
                }

                dao.FecharConexao();
            }

        }

        #endregion

        #region Metodos Auxiliares
        private Turma CarregarTurma(MySqlDataReader dr)
        {
            int id = dr.GetInt32("Id_Turma");
            String local = dr.GetString("LocalTurma");
            int qtdeVagas = dr.GetInt32("QtdeVagas");
            DateTime dataInicial = dr.GetDateTime("DataInicial");
            string horarios = dr.GetString("Horarios");
            DateTime dataFinal = dr.GetDateTime("DataFinal");
            double precoAtual = dr.GetDouble("PrecoAtual");
            int idCursoJornada = dr.GetInt32("Id_CursoJornada");
            string nome = dr.GetString("Nome");



            Turma turma = new Turma(id, local, qtdeVagas, dataInicial, dataFinal, horarios, precoAtual, null, null, nome, null, null);
            turma.IdJornadaCurso = idCursoJornada;

            return turma;
        } 
        #endregion
    }
}
